﻿using System;
using System.Runtime.InteropServices;
using ArgusLib.InteropServices;
using ArgusLib.FFmpeg.avutil;
using uint64_t = System.UInt64;
using uint8_t = System.Byte;

namespace ArgusLib.FFmpeg.avcodec.Interop
{
	[StructLayout(LayoutKind.Sequential)]
	public class AVCodecNative
	{
		[MarshalAs(UnmanagedType.LPStr)]
		public string name;

		[MarshalAs(UnmanagedType.LPStr)]
		public string long_name;

		public AVMediaType type;
		public AVCodecID id;
		public CodecCapabilities capabilities;
		public IntPtr supported_framerates;
		public IntPtr pix_fmts;
		public IntPtr supported_samplerates;
		public IntPtr sample_fmts;
		public IntPtr channel_layouts;
		public uint8_t max_lowres;
		public IntPtr priv_class;
		public IntPtr profiles;

#if false
	/*****************************************************************
	 * No fields below this line are part of the public API. They
	 * may not be used outside of libavcodec and can be changed and
	 * removed at will.
	 * New public fields should be added right above.
	 *****************************************************************
	 */
	int priv_data_size;
	struct AVCodec *next;
	/**
	 * @name Frame-level threading support functions
	 * @{
	 */
	/**
	 * If defined, called on thread contexts when they are created.
	 * If the codec allocates writable tables in init(), re-allocate them here.
	 * priv_data will be set to a copy of the original.
	 */
	int (*init_thread_copy)(AVCodecContext *);
	/**
	 * Copy necessary context variables from a previous thread context to the current one.
	 * If not defined, the next thread will start automatically; otherwise, the codec
	 * must call ff_thread_finish_setup().
	 *
	 * dst and src will (rarely) point to the same context, in which case memcpy should be skipped.
	 */
	int (*update_thread_context)(AVCodecContext *dst, const AVCodecContext *src);
	/** @} */

	/**
	 * Private codec-specific defaults.
	 */
	const AVCodecDefault *defaults;

	/**
	 * Initialize codec static data, called from avcodec_register().
	 */
	void (*init_static_data)(struct AVCodec *codec);

	int (*init)(AVCodecContext *);
	int (*encode_sub)(AVCodecContext *, uint8_t *buf, int buf_size,
					  const struct AVSubtitle *sub);
	/**
	 * Encode data to an AVPacket.
	 *
	 * @param      avctx          codec context
	 * @param      avpkt          output AVPacket (may contain a user-provided buffer)
	 * @param[in]  frame          AVFrame containing the raw data to be encoded
	 * @param[out] got_packet_ptr encoder sets to 0 or 1 to indicate that a
	 *                            non-empty packet was returned in avpkt.
	 * @return 0 on success, negative error code on failure
	 */
	int (*encode2)(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame,
				   int *got_packet_ptr);
	int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, AVPacket *avpkt);
	int (*close)(AVCodecContext *);
	/**
	 * Flush buffers.
	 * Will be called when seeking
	 */
	void (*flush)(AVCodecContext *);
#endif
	}
}
